﻿using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Collections.Generic;
using System.IO;

namespace Ricebird.Wordprocessing
{
    public class WordDocument : IDisposable
    {
        internal WordprocessingDocument InternalDocument
        {
            get; set;
        } = null;

        #region ctor
        private WordDocument()
        {

        }
        #endregion

        #region 创建对象
        /// <summary>
        /// 创建一个Word对象
        /// </summary>
        /// <returns></returns>
        public static WordDocument CreateDocument()
        {
            WordDocument doc = new WordDocument();
            doc.InternalDocument = WordprocessingDocument.Create(new MemoryStream(), DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
            doc.InitializeDocument();
            return doc;
        }

        /// <summary>
        /// 读取一个Word文档
        /// </summary>
        /// <param name="path">文档路径</param>
        /// <param name="createNew">如果文件已经存在，是否删除原文件</param>
        /// <returns></returns>
        public static WordDocument CreateDocument(string path, bool createNew)
        {
            if (createNew && File.Exists(path))
            {
                File.Delete(path);
            }

            WordDocument doc = new WordDocument();
            if (File.Exists(path))
            {
                doc.InternalDocument = WordprocessingDocument.Open(path, true);
            }
            else
            {
                doc.InternalDocument = WordprocessingDocument.Create(path, DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
            }
            doc.InitializeDocument();
            return doc;
        }

        /// <summary>
        /// 读取一个Word文档
        /// </summary>
        /// <param name="path">文档路径</param>
        /// <param name="createNew">如果文件已经存在，是否删除原文件</param>
        /// <returns></returns>
        public static WordDocument CreateDocumentByTemplate(string path)
        {
            if (!File.Exists(path))
            {
                throw new FileNotFoundException($"找不到名为'{path}'的文件");
            }

            MemoryStream ms = null;
            using (FileStream fs = new FileStream(path, FileMode.Open))
            {
                ms = new MemoryStream((int)fs.Length);

                byte[] buffer = new byte[1024 * 1024 * 5];

                //因为文件可能比较大所以在读取的时候应该用循坏去读取
                while (true)
                {
                    //返回本次实际读取到的字节数
                    int r = fs.Read(buffer, 0, buffer.Length);

                    if (r == 0)
                    {
                        break;
                    }
                    ms.Write(buffer, 0, r);//写入
                }
            }

            WordDocument doc = new WordDocument();
            doc.InternalDocument = WordprocessingDocument.Open(ms, true);
            doc.InitializeDocument();
            return doc;
        }
        #endregion

        #region 初始化文档
        protected void InitializeDocument()
        {
            var doc = InternalDocument;
            if (doc.MainDocumentPart == null)
            {
                doc.AddMainDocumentPart();
            }
            
            if (doc.MainDocumentPart.Document == null)
            {
                doc.MainDocumentPart.Document = new Document();
            }

            if (doc.MainDocumentPart.Document.Body == null)
            {
                doc.MainDocumentPart.Document.Body = new Body();
            }
        }
        #endregion

        #region 样式
        /// <summary>
        /// 创建一个样式
        /// </summary>
        /// <param name="name"></param>
        /// <param name="builder"></param>
        /// <returns></returns>
        public WordStyles CreateStyle(string name, Action<WordStyles> builder)
        {
            WordStyles style = new WordStyles(name, this);
            builder(style);
            return style;
        }

        internal WordStyles DefaultStyle
        {
            get; set;
        } = null;

        public WordDocument SetDefaultStyle(WordStyles style)
        {
            DefaultStyle = style;
            return this;
        }
        #endregion

        #region 添加段落
        public CompositeElementBase AppendParagraph()
        {
            return AppendParagraph(DefaultStyle);
        }

        public CompositeElementBase AppendParagraph(string text)
        {
            return AppendParagraph(text, DefaultStyle);
        }

        public CompositeElementBase AppendParagraph(WordStyles style)
        {
            var body = InternalDocument.MainDocumentPart.Document.Body;
            Paragraph para = new Paragraph();
            body.Append(para);
            WordParagraph wpara = new WordParagraph(para, this);
            wpara.SetStyle(style);
            return wpara;
        }

        public CompositeElementBase AppendParagraph(string text, WordStyles style)
        {
            var para = AppendParagraph();
            para.Append(text);
            para.SetStyle(style);
            return para;
        }
        #endregion

        #region 保存函数
        /// <summary>
        /// 保存函数
        /// </summary>
        public void Save()
        {
            InternalDocument.Save();
        }

        /// <summary>
        /// 另存为函数
        /// </summary>
        /// <param name="path"></param>
        /// <param name="isCreated">如果文件存在是否删除</param>
        public void SaveAs(string path, bool isCreated = false)
        {
            if (File.Exists(path))
            {
                if (isCreated)
                {
                    File.Delete(path);
                }
                else
                {
                    throw new InvalidOperationException($"文件'{path}'已经存在");
                }
            }
            InternalDocument.SaveAs(path);
        }
        #endregion

        public void Dispose()
        {
            InternalDocument?.Dispose();
        }
    }
}
